<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }

        .datebox {
            position: absolute;
            left: 0;
            width: 210px;
            height: 240px;
            background-color: #0b333f;
        }

        .date-header {
            height: 30px;
            width: 210px;
        }

        .date-header span {
            float: left;
            height: 30px;
            text-align: center;
            line-height: 30px;
            background-color: #0b333f;
            color: #ffffff;
        }

        .date-header .date-prev {
            width: 20%;
        }

        .date-header .date-next {
            width: 20%;
        }

        .date-header .date-middle {
            width: 60%;
        }

        .date-th {
            width: 210px;
            height: 30px;
        }

        .date-th li {
            float: left;
            height: 30px;
            width: 30px;
            text-align: center;
            line-height: 30px;
            background-color: #0b333f;
            color: #ffffff;
        }

        .date-content {
            width: 210px;
            height: 180px;
        }

        .date-content li {
            float: left;
            height: 30px;
            width: 30px;
            text-align: center;
            line-height: 30px;
            background-color: #0b333f;
            color: #ffffff;
        }
    </style>
</head>
<body>
<input id="start">
<input id="end">
</body>
<script>
    Date.prototype.getDays = function () {
        var temp = new Date("2000-01-01");
        temp.setFullYear(this.getFullYear());//2018
        temp.setMonth(this.getMonth() + 1);//12  1
        temp.setDate(0);//11 30
        return temp.getDate();
    }
    Date.prototype.getPrevMonthDays = function () {
        var temp = new Date("2000-01-01");
        temp.setFullYear(this.getFullYear());//2018
        temp.setMonth(this.getMonth());//11
        temp.setDate(0);//10 31
        return temp.getDate();
    }
    Date.prototype.firstDayWeek = function () {
        var temp = new Date("2000-01-01");
        temp.setFullYear(this.getFullYear());//2018
        temp.setMonth(this.getMonth());//11
        temp.setDate(1);//10 31
        return temp.getDay();
    }
    Date.prototype.dateformat = function (str) {
        var year = this.getFullYear();
        var month = this.getMonth() + 1;
        var day = this.getDate();
        return str.replace("yyyy", year).replace("mm", month).replace("dd", day);
    }
    function DatePicker(ele, json) {
        this.target = document.querySelector(ele);
        var that = this;
        this.option = {
            date: new Date(),
            dateformat: "yyyy-mm-dd"
        }
        this.extend(json);
        this.target.onclick = function (e) {
            var evt = window.event || e;
            evt.stopPropagation();
            that.create();//创造结构
            that.bindData();//生成数据结构

        }
    }
    DatePicker.prototype.extend = function (json) {
        for (var i in json) {
            if (i == "date") {
                this.option["date"] = new Date(json[i]);
            } else {
                this.option[i] = json[i];
            }
        }

    }
    DatePicker.prototype.bindEvent = function () {
        var that = this;
        this.nextBtn.onclick = function (e) {
            that.option["date"].setMonth(that.option["date"].getMonth() + 1);
            that.bindData();
            var evt = window.event || e;
            evt.stopPropagation();
        }
        this.prevBtn.onclick = function (e) {
            that.option["date"].setMonth(that.option["date"].getMonth() - 1);
            that.bindData();
            var evt = window.event || e;
            evt.stopPropagation();
        }

//        document.onclick = function () {
//            that.hide();
//        }
        document.addEventListener("click", function () {
            that.hide();
        })

    }

    DatePicker.prototype.bindData = function () {
        var that = this;
        var week = this.option["date"].firstDayWeek();
        week = week == 0 ? 7 : week;//表示星期几
        var days = this.option["date"].getDays();//表示当月有多少天
        var prevDays = this.option["date"].getPrevMonthDays();//上一月有多少天

        //分为三层
        //上
        this.content.innerHTML = "";
        for (var i = (prevDays - week + 2); i <= prevDays; i++) {
            var li = document.createElement("li");
            li.innerHTML = i;
            li.style.backgroundColor = "#cdcdcd";
            this.content.appendChild(li);
        }
        //当
        for (var i = 1; i <= days; i++) {
            var li = document.createElement("li");
            li.innerHTML = i;
            li.date = new Date(this.option.date.getFullYear(), this.option.date.getMonth(), i).dateformat(this.option["dateformat"]);
            this.content.appendChild(li);
            li.onclick = function (e) {
//                alert(this.date);
                var evt = window.event || e;
                evt.stopPropagation();
                var temp = new Date();
                var year = temp.getFullYear();
                var month = temp.getMonth() + 1;
                var day = temp.getDate();
                var date = new Date(`${year}-${month}-${day} 00:00:00`);
                var clickDate = new Date(this.date + " 00:00:00");
                if (clickDate < date) {
                    alert("过期时间不能点击");
                } else {
                    that.target.value = this.date;
                    that.hide();
                }
            }
        }
        //下
        for (var i = 1; i <= (42 - days - week + 1); i++) {
            var li = document.createElement("li");
            li.innerHTML = i;
            li.style.backgroundColor = "#cdcdcd";
            this.content.appendChild(li);
        }

        this.middle.innerHTML = this.option.date.dateformat("yyyy-mm");
        this.bindEvent();
    }
    DatePicker.prototype.hide = function () {
        this.datebox.style.display = "none";
    }
    DatePicker.prototype.show = function () {
        this.datebox.style.display = "block";
    }

    DatePicker.prototype.create = function () {

        if (this.box) {
            this.show();
        } else {
            this.box = document.createElement("div");
            this.box.className = "datepicker-box";
//        this.box.style.border = "1px solid red";
            this.box.style.width = this.target.offsetWidth + "px";
            this.box.style.height = this.target.offsetHeight + "px";
            this.target.parentNode.insertBefore(this.box, this.target);
            this.box.style.display = "inline-block";
            this.box.style.position = "relative";
            this.box.appendChild(this.target);

            this.datebox = document.createElement("div");
            this.datebox.className = "datebox";
            this.datebox.style.top = this.target.offsetHeight + 10 + "px";
            this.box.appendChild(this.datebox);

            this.header = document.createElement("div");
            this.header.className = "date-header";
            this.datebox.appendChild(this.header);

            this.prevBtn = document.createElement("span");
            this.prevBtn.className = "date-prev";
            this.prevBtn.innerHTML = "上";
            this.header.appendChild(this.prevBtn);

            this.middle = document.createElement("span");
            this.middle.className = "date-middle";
            this.middle.innerHTML = "2018年11月";
            this.header.appendChild(this.middle);

            this.nextBtn = document.createElement("span");
            this.nextBtn.className = "date-next";
            this.nextBtn.innerHTML = "下";
            this.header.appendChild(this.nextBtn);

            this.th = document.createElement("ul");
            this.th.className = "date-th";
            this.th.innerHTML = `<li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li><li>日</li>`;
            this.datebox.appendChild(this.th);

            this.content = document.createElement("ul");
            this.content.className = "date-content";
            this.datebox.appendChild(this.content);
        }
    }

    new DatePicker("#start", {date: "2018-10-01", dateformat: "yyyy年mm月dd日"});

    new DatePicker("#end");

</script>
</html>